#include "WLockGuard.hpp"
#include "WSpinMutex.hpp"
#include "WReadWriteMutex.hpp"
#include <thread>
#include <vector>

using namespace std;

WSpinMutex g_mutex;
int g_data = 0;

WReadWriteMutex g_rwMutex;
int g_rwData = 10;

void testRead()
{
    g_rwMutex.readLock();
    std::cout << "testRead g_rwData is " << g_rwData << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(3000));
    g_rwMutex.readUnlock();
}

void testWrite()
{
    g_rwMutex.writeLock();
    g_rwData = 12;
    std::cout << "testWrite g_rwData is " << g_rwData << std::endl;
    g_rwMutex.writeUnlock();
}

void test()
{
    WLockGuard<WSpinMutex> locker(&g_mutex);
    for(int i = 0; i < 100; i++)
    {
        g_data++;
    }
}

int main(int argc, char *argv[])
{
    vector<thread> threadList;
    for (int i = 0; i < 8; i++)
    {
        threadList.emplace_back(test);
    }

    for (int i = 0; i < 8; i++)
    {
        threadList[i].join();
    }

    std::cout << "g_data is " << g_data << std::endl;

    std::thread readThread1(testRead);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    std::thread writeThread1(testWrite);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    std::thread readThread2(testRead);
    readThread1.join();
    readThread2.join();
    writeThread1.join();
    return 0;
}
